#ifndef CHAINOFRESPONSIBILITY_PATTERN_H
#define CHAINOFRESPONSIBILITY_PATTERN_H

#include <string>

using namespace std;

class AbstractLogger
{
public:
    virtual ~AbstractLogger() {}

    void setNextLogger(AbstractLogger* nextLogger);
    void logMessage(int level, string message);

    virtual void write(string message) = 0;

public:
    enum { INFO = 1, DEBUG = 2, ERROR = 3};

protected:
    int level;
    AbstractLogger* nextLogger;
};

class ConsoleLogger : public AbstractLogger
{
public:
    ConsoleLogger(int level);
    ~ConsoleLogger() {}

protected:
    void write(string message) override;
};

class ErrorLogger : public AbstractLogger
{
public:
    ErrorLogger(int level);
    ~ErrorLogger() {}

protected:
    void write(string message) override;
};

class FileLogger : public AbstractLogger
{
public:
    FileLogger(int level);
    ~FileLogger() {}

protected:
    void write(string message) override;
};

#endif // CHAINOFRESPONSIBILITY_PATTERN_H

/*
    AbstractLogger* getChainOfLogger()
    {
        AbstractLogger* errorLogger = new ErrorLogger(AbstractLogger::ERROR);
        AbstractLogger* fileLogger = new FileLogger(AbstractLogger::DEBUG);
        AbstractLogger* consoleLogger = new ConsoleLogger(AbstractLogger::INFO);

        errorLogger->setNextLogger(fileLogger);
        fileLogger->setNextLogger(consoleLogger);

        return errorLogger;
    }

    ------------------------------
    AbstractLogger* loggerChain = getChainOfLogger();
    loggerChain->logMessage(AbstractLogger::INFO, "This is an information.");

    loggerChain->logMessage(AbstractLogger::DEBUG, "This is a debug level information.");

    loggerChain->logMessage(AbstractLogger::ERROR, "This is an error information.");
*/
